Sublime Textの補完機構の詳細の概略
概要
Sublime Text シリーズで、補完を出すAPIについて調べるチャンスがあったので、
纏めておく。
Sublime Textにおける補完とは
こんな感じの見た目で出る、補完お助け機能みたいなの。
左がメソッドとかクラス名とか。右が返りの型、に”してみた”。
エディタに出てるとこだとこんなの。
入力選択はSublimeお得意のファジーさを発揮し、補完開始すると、
tabキーでのパラメータ入力移動とかがある。
EclipseとかIDEのアレと一緒。
API
ドキュメントに無い(殺)APIを使う。
def on_query_completions(self, view, prefix, locations):
なんで無いのかForumで問いただして見ているところ。
動作内容
候補のフォーマットがわからん。で、調べたところ、最終的に
https://gist.github.com/agibsonsw/2030626
あたりが参考になった。
このAPIは、
・特定の形式の(str,str)のtupleが入ったlistをこのAPIのオーバーライドをしたメソッドから返すようにすると、それらを補完候補として出す
・view.run_command("auto_complete") で任意のタイミングで呼び出せる
・view.run_command("hide_auto_complete") で任意のタイミングで消せる
という特性がある。
補完候補に出てさえしまえば、あとはSublimeお得意のファジィーなマッチがエクセレントするので、ラク。
っていうかドキュメントォォォォ
このAPIの使い方
他のハンドラAPIと同様、overrideする。
class CaptureEditing(sublime_plugin.EventListener):
def on_query_completions(self, view, prefix, locations):
return [("compile\tcompile fn", "compile(${1:source}, ${2:filename}, ${3:mode}${4:[, flags]}${5:[, dont_inherit]})$0")]
書式
このAPIから下記のようなlistデータを返すと補完ウインドウが出る。
[("compile\tcompile fn", "compile(${1:source}, ${2:filename}, ${3:mode}${4:[, flags]}${5:[, dont_inherit]})$0")]
で、候補として表示される内容は
compile[タブ]compile fn
になる。
この補完を選択後にコードに入力されるデータは下記になる。
compile(source, filename, mode[, flags][, dont_inherit])
()の中身はtabで右に移動、space+tabで左に移動できる。
= $マーク+数字で、tabキーでの移動候補になっている、と考えるとしっくりくる。
詳細
listの中の各要素が補完候補になっている。
文字列のtupleになっていて、
("compile\tcompile fn", "compile(${1:source}, ${2:filename}, ${3:mode}${4:[, flags]}${5:[, dont_inherit]})$0")
の最初の値
"compile\tcompile fn"
は、補完の説明文になっている。
返り値、メソッド名とかがいい感じ。
tabで区切ると左端、右端にそれぞれが表示される。
次の値は、
"compile(${1:source}, ${2:filename}, ${3:mode}${4:[, flags]}${5:[, dont_inherit]})$0"
文字列()$0
この$0は、全体を入力し終わった際に、最後にtabキーで到達できる場所になっている。
${数字:パラメータ文字列} は、
$が内容を範囲で持つ場合、このパラメータ名を枠として、文字入力できる動作になる。
ちなみにパラメータ文字列部分を[, 文字列]にすることで、not needを表明できる、みたいなオプションもある。
overloadとかのときに使うと良い。
使い道
と、表示するための情報とかは楽に出せるんだけど、Sublime TextからこのAPIをちゃんと使うには、
・入力状況から特定のタイミングを検知するようにイベントトリガーを設置する
・トリガーが正しいかどうか入力中バッファの状況を見て判断する
・データを読んで、補完内容を選出する
・補完内容を配列として返す
というシークエンスが必要で、コレを全部プラグイン内で実行しないといけなくて大変。
コンパイルの結果を流用できるような規模でないと、とても作れないと思う。
簡単なまとめまでに。